package top.lixunda.ecommerce.server.good.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.lixunda.commerce.common.core.entity.MessageObject;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.common.utils.alipay.AlipayClientUtils;
import top.lixunda.common.validate.XumValid;
import top.lixunda.ecommerce.server.business.BaseController;
import top.lixunda.ecommerce.server.business.api.entity.dto.PageConvertDTO;
import top.lixunda.ecommerce.server.good.api.entity.db.GoodOrderDO;
import top.lixunda.ecommerce.server.good.api.entity.dto.AdminOrderDetailQueryDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.GoodOrderInsertDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.OrderDetailQueryDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.StoreOrderDetailQueryDTO;
import top.lixunda.ecommerce.server.good.api.entity.vo.OrderConvertVO;
import top.lixunda.ecommerce.server.good.api.entity.db.OrderDetailDO;
import top.lixunda.ecommerce.server.good.api.controller.IOrderDetailController;
import top.lixunda.ecommerce.server.good.service.IOrderDetailService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author Xumda
 * @version time:2020/1/10 16:10
 */
@Slf4j
@RestController
public class OrderDetailController extends BaseController
        implements IOrderDetailController {

    private final IOrderDetailService orderDetailService;

    @Autowired
    public OrderDetailController(IOrderDetailService orderDetailService) {
        this.orderDetailService = orderDetailService;
    }

    /**
     * 根据订单id查看订单信息，但api可以查看本人的所有订单
     *
     * @param id 订单id
     * @return 订单详细数据
     */
    @Override
    public MessageObject<OrderConvertVO> queryOrderDetailById(Integer id) {
        if (id == null || id <= 0) {
            return getErrorMessageObject("id不能空且不能小于等于零");
        }
        List<OrderConvertVO> list = orderDetailService.queryOrderDetailByIds(Collections.singletonList(id));
        if (ObjectValidators.isEmpty(list)) {
            throw getAppException("订单数据不存在");
        }
        return getSuccessMessageObject("获取订单数据成功", list.get(0));
    }

    /**
     * 根据订单id查看多个订单信息，但api可以查看本人的所有订单, 默认根据时间排序
     *
     * @param ids 订单id
     * @return 订单详细数据
     */
    @Override
    public MessageObject<List<OrderConvertVO>> queryOrderDetailByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("参数不能为空");
        }
        List<OrderConvertVO> list = orderDetailService.queryOrderDetailByIds(ids);
        return getSuccessMessageObject("获取订单数据成功", list);
    }

    /**
     * 分页条件查询
     *
     * @param pageDTO 分页数据和提哦啊见数据
     * @return 订单详细数据列表
     */
    @Override
    public MessageObject<IPage<OrderConvertVO>> queryOrderDetailPageWrapper(
            @XumValid PageConvertDTO<GoodOrderDO, OrderDetailDO, OrderDetailQueryDTO> pageDTO) {
        IPage<OrderConvertVO> page = orderDetailService.queryOrderDetailPageWrapper(pageDTO);
        return getSuccessMessageObject("获取订单数据成功", page);
    }

    /**
     * 店铺调用，根据订单id查看订单信息，但api可以查看本人的所有订单
     *
     * @param id 订单id
     * @return 订单详细数据
     */
    @Override
    public MessageObject<OrderConvertVO> queryOrderDetailByIdStore(@RequestParam("id") Integer id) {
        if (id == null || id <= 0) {
            return getErrorMessageObject("id不能空且不能小于等于零");
        }
        List<OrderConvertVO> list = orderDetailService.queryOrderDetailByIdsStore(Collections.singletonList(id));
        if (ObjectValidators.isEmpty(list)) {
            throw getAppException("订单数据不存在");
        }
        return getSuccessMessageObject("获取订单数据成功", list.get(0));
    }

    /**
     * 店铺调用，根据订单id查看多个订单信息，但api可以查看本人的所有订单, 默认根据时间排序
     *
     * @param ids 订单id
     * @return 订单详细数据
     */
    @Override
    public MessageObject<List<OrderConvertVO>> queryOrderDetailByIdsStore(@RequestBody List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("参数不能为空");
        }
        List<OrderConvertVO> list = orderDetailService.queryOrderDetailByIdsStore(ids);
        return getSuccessMessageObject("获取订单数据成功", list);
    }

    /**
     * 店铺调用，分页条件查询
     *
     * @param pageDTO 分页数据和提哦啊见数据
     * @return 订单详细数据列表
     */
    @Override
    public MessageObject<IPage<OrderConvertVO>> queryOrderDetailPageWrapperStore(
            @XumValid PageConvertDTO<GoodOrderDO, OrderDetailDO, StoreOrderDetailQueryDTO> pageDTO) {
        IPage<OrderConvertVO> page = orderDetailService.queryOrderDetailPageWrapperStore(pageDTO);
        return getSuccessMessageObject("获取订单数据成功", page);
    }

    /**
     * 管理员调用，根据订单id查看订单信息，但api可以查看本人的所有订单
     *
     * @param id 订单id
     * @return 订单详细数据
     */
    @Override
    public MessageObject<OrderConvertVO> queryOrderDetailByIdAdmin(@RequestParam("id") Integer id) {
        if (id == null || id <= 0) {
            return getErrorMessageObject("id不能空且不能小于等于零");
        }
        List<OrderConvertVO> list = orderDetailService.queryOrderDetailByIdsAdmin(Collections.singletonList(id));
        if (ObjectValidators.isEmpty(list)) {
            throw getAppException("订单数据不存在");
        }
        return getSuccessMessageObject("获取订单数据成功", list.get(0));
    }

    /**
     * 管理员调用，根据订单id查看多个订单信息，但api可以查看本人的所有订单, 默认根据时间排序
     *
     * @param ids 订单id
     * @return 订单详细数据
     */
    @Override
    public MessageObject<List<OrderConvertVO>> queryOrderDetailByIdsAdmin(@RequestBody List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("参数不能为空");
        }
        List<OrderConvertVO> list = orderDetailService.queryOrderDetailByIdsAdmin(ids);
        return getSuccessMessageObject("获取订单数据成功", list);
    }

    /**
     * 管理员调用，分页条件查询
     *
     * @param pageDTO 分页数据和提哦啊见数据
     * @return 订单详细数据列表
     */
    @Override
    public MessageObject<IPage<OrderConvertVO>> queryOrderDetailPageWrapperAdmin(
            @XumValid PageConvertDTO<GoodOrderDO, OrderDetailDO, AdminOrderDetailQueryDTO> pageDTO) {
        IPage<OrderConvertVO> page = orderDetailService.queryOrderDetailPageWrapperAdmin(pageDTO);
        return getSuccessMessageObject("获取订单数据成功", page);
    }

    /**
     * 用户调用，根据id删除订单
     *
     * @param ids 订单id列表
     * @return 是否删除成功
     */
    @Override
    public MessageObject<Boolean> removeOrderByIds(@RequestBody List<Integer> ids) {
        Boolean success = orderDetailService.removeOrderByIds(ids);
        return success ? getSuccessMessageObject("操作成功", true)
                : getErrorMessageObject("操作失败", false);
    }

    /**
     * 店家调用，根据id删除订单
     *
     * @param ids 订单id列表
     * @return 是否删除成功
     */
    @Override
    public MessageObject<Boolean> removeOrderByIdsStore(@RequestBody List<Integer> ids) {
        Boolean success = orderDetailService.removeOrderByIdsStore(ids);
        return success ? getSuccessMessageObject("操作成功", true)
                : getErrorMessageObject("操作失败", false);
    }

    /**
     * 直接购买商品，生成订单
     *
     * @param goodOrderInsertDTO DTO
     * @return OrderConvertVO
     */
    @Override
    public MessageObject<OrderConvertVO> insertGoodOrderDTO(
            @XumValid @RequestBody GoodOrderInsertDTO goodOrderInsertDTO) {
        OrderConvertVO vo = orderDetailService.insertGoodOrderDTO(goodOrderInsertDTO);
        return getSuccessMessageObject("生成订单成功", vo);
    }

    /**
     * 根据id取消订单
     *
     * @param ids 取消订单的订单编号
     * @return 取消的订单数据
     */
    @Override
    public MessageObject<List<OrderConvertVO>> cancelOrderByIds(List<Integer> ids) {
        List<OrderConvertVO> list = orderDetailService.cancelOrderByIds(ids);
        return getSuccessMessageObject("取消订单成功", list);
    }

    /**
     * 订单支付
     *
     * @param response HttpServletResponse
     * @param id       订单id
     * @param returnUrl 支付返回地址
     * @throws IOException 通过Response向前端写数据异常
     */
    @Override
    public void payOrderById(Integer id, String returnUrl, HttpServletResponse response) throws IOException {
        String html = orderDetailService.toPayOrderPage(id, returnUrl);
        AlipayClientUtils.writeToResponse(response, html);
    }

    /**
     * 订单支付通知消息
     *
     * @param map 参数
     * @param request HttpServletRequest
     * @return 是否成功
     */
    @Override
    public MessageObject<Boolean> payOrderNotifyCallback(
            @RequestParam Map<String, String> map, HttpServletRequest request) {
        String message = orderDetailService.payOrderNotifyCallback(map, request);
        return ObjectValidators.isEmpty(message) ? getSuccessMessageObject("支付成功", true) :
                getErrorMessageObject("支付失败", false);
    }

    /**
     * 用户调用，申请退款，申请后由店家验证退款
     *
     * @param orderId 订单编号
     * @param message 申请理由
     * @return 是否申请成功
     */
    @Override
    public MessageObject<Boolean> applyRefundByOrderId(Integer orderId, String message) {
        Boolean success = orderDetailService.applyRefundByOrderId(orderId, message);
        return success ? getSuccessMessageObject("申请退款成功", true) :
                getErrorMessageObject("申请退款失败", false);
    }

    /**
     * 用户调用，根据申请id取消退款申请
     *
     * @param id 退款申请id
     * @return 是否取消成功
     */
    @Override
    public MessageObject<Boolean> applyRefundCancelById(Integer id) {
        Boolean success = orderDetailService.applyRefundCancelById(id);
        return success ? getSuccessMessageObject("取消申请", true) :
                getErrorMessageObject("取消申请失败", false);
    }

    /**
     * 用户调用，根据订单id取消退款申请
     *
     * @param orderId 订单id
     * @return 是否取消成功
     */
    @Override
    public MessageObject<Boolean> applyRefundCancelByOrderId(Integer orderId) {
        Boolean success = orderDetailService.applyRefundCancelByOrderId(orderId);
        return success ? getSuccessMessageObject("取消申请", true) :
                getErrorMessageObject("取消申请失败", false);
    }

    /**
     * 商家调用，根据订单编号对订单进行退款操作
     *
     * @param id 订单编号
     * @return 是否退款成功
     */
    @Override
    public MessageObject<Boolean> refundByOrderId(Integer id) {
        Boolean success = orderDetailService.refundByOrderId(id);
        return success ? getSuccessMessageObject("退款成功", true) :
                getErrorMessageObject("退款失败", false);
    }

    /**
     * 用户调用，根据订单编号移除订单
     *
     * @param id 订单编号
     * @return 是否移除成功
     */
    @Override
    public MessageObject<Boolean> removeOrderUserById(Integer id) {
        Boolean success = orderDetailService.removeOrderUserById(id);
        return success ? getSuccessMessageObject("移除成功", true) :
                getErrorMessageObject("移除失败", false);
    }

    /**
     * 店铺调用，根据订单编号移除订单
     *
     * @param id 订单编号
     * @return 是否移除成功
     */
    @Override
    public MessageObject<Boolean> removeOrderStoreById(Integer id) {
        Boolean success = orderDetailService.removeOrderStoreById(id);
        return success ? getSuccessMessageObject("移除成功", true) :
                getErrorMessageObject("移除失败", false);
    }

}
